package soar.test.exception;

import java.util.LinkedList;
import java.util.stream.Collectors;

public class App
{
    public static void main(String[] args)
    {
        new App().run();
    }

    private void run()
    {
        try
        {
            String split = "========================================";

            exception();
            System.out.println(split);

            throw_exception();
            System.out.println(split);
        }
        catch (Exception e)
        {
            System.err.println(e);
        }
    }

    private void exception()
    {
        System.out.println("excepion");
        String split = "------------------------------";
        System.out.println(split);

        try
        {
            throw new Exception("fail");
        }
        catch (Exception e)
        {
            System.out.println(String.format("e: %s", e));
            System.out.println(split);

            System.out.println(String.format("toString: %s", e.toString()));
            System.out.println(split);

            System.out.println(String.format("getMessage: %s", e.getMessage()));
            System.out.println(split);

            System.out.println(String.format("getStackTrace:"));
            StackTraceElement[] stack = e.getStackTrace();
            for (StackTraceElement el : stack)
            {
                System.out.println(el.toString());
            }
        }
    }

    private void throw_exception()
    {
        System.out.println("throw_exception");
        String split = "------------------------------";
        System.out.println(split);

        try
        {
            func();
        }
        catch (Exception e)
        {
            System.out.println(String.format("%s", e.toString()));
            System.out.println(split);

            System.out.println("StackTrace");
            System.out.println();
            StackTraceElement[] stack = e.getStackTrace();
            for (StackTraceElement el : stack)
            {
                System.out.println(el.toString());

                System.out.println("class: " + el.getClassName());
                System.out.println("method: " + el.getMethodName());

                System.out.println();
            }
            System.out.println(split);

            System.out.println("当前点 --> 异常抛出点");
            System.out.println();

            StackTraceElement curr = Thread.currentThread().getStackTrace()[1];
            String curr_method = curr.getClassName() + "."
                    + curr.getMethodName();
            System.out.println("当前点: " + curr_method);
            System.out.println();

            LinkedList<StackTraceElement> methods = new LinkedList<>();
            for (StackTraceElement el : stack)
            {
                methods.addFirst(el);
                String method = el.getClassName() + "." + el.getMethodName();
                if (method.equals(curr_method))
                {
                    break;
                }
            }
            System.out
                    .println(String.format("%s: %s",
                            methods.stream().map(x -> x.toString())
                                    .collect(Collectors.joining(" --> ")),
                            e.toString()));
        }
    }

    private void func()
    {
        fail();
    }

    private void fail()
    {
        String[] arr = { "a", "b", "c" };
        arr[arr.length] = "more";
    }
}
